﻿//-----------------------------------------------------------------------
// <copyright file="StackExchangeUserParser.cs" company="billfellows.net">
//     I mention copyright so StyleCop is happy.
// </copyright>
//-----------------------------------------------------------------------
namespace ReputationMinder
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using HtmlAgilityPack;

    /// <summary>
    /// A class for scraping the user's page to extract reputation and last seen
    /// </summary>
    public class StackExchangeUserParser
    {
        /// <summary>
        /// Local reference to the original HTML
        /// </summary>
        private string html;

        /// <summary>
        /// An instance of our snapshot object, used for saving data
        /// </summary>
        private EntitySnapshot snap;

        /// <summary>
        /// Initializes a new instance of the StackExchangeUserParser class.
        /// </summary>
        /// <param name="content">The html to be parsed</param>
        public StackExchangeUserParser(string content)
        {
            this.html = content;
            this.snap = new EntitySnapshot();
        }

        /// <summary>
        /// Gets or sets the time the crawl was performed
        /// </summary>
        public DateTime SnapshotTS { get; set; }

        /// <summary>
        /// Gets or sets the unique user's id
        /// </summary>
        public int EntityID { get; set; }

        /// <summary>
        /// Attempt to parse the content into parts and persist to our database
        /// </summary>
        public void Parse()
        {
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(this.html);
            string reputationXpath = @"//*[@id=""large-user-info""]/div[1]/div[1]/div[1]/span/a";
            string seenXpath = @"//*[@id=""large-user-info""]/div[1]/div[2]/table/tbody[2]/tr[2]/td[2]";

            foreach (HtmlNode row in doc.DocumentNode.SelectNodes(reputationXpath))
            {
                try
                {
                    if (row.ChildNodes.Count == 1)
                    {
                        string reputation = row.ChildNodes.First().InnerText;

                        this.snap.EntityID = this.EntityID;
                        this.snap.SnapshotTS = this.SnapshotTS;
                        this.snap.Reputation = int.Parse(reputation.Replace(",", string.Empty));
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    throw;
                }
            }

            foreach (HtmlNode row in doc.DocumentNode.SelectNodes(seenXpath))
            {
                try
                {
                    string seenText = row.Attributes[1].Value;
                    DateTime seen = DateTime.Parse(seenText);
                    this.snap.LastSeen = seen;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    throw;
                }
            }

            this.snap.Save();
        }
    }
}
